<!--
 * @Author: early-autumn
 * @Date: 2020-05-30 17:00:25
 * @LastEditors: early-autumn
 * @LastEditTime: 2020-06-17 15:34:07
-->
<template>
  <el-card class="order-edit" shadow="never">
    <el-table
      :data="tableData"
      :summary-method="getSummaries"
      border
      show-summary
    >
      <el-table-column
        align="center"
        label="项目名称"
        min-width="150"
        prop="itemName"
      ></el-table-column>
      <el-table-column align="center" label="牙位" min-width="120">
        <ct-modules
          v-model="scope.row.toothPosition"
          slot-scope="scope"
        ></ct-modules>
      </el-table-column>
      <el-table-column
        align="center"
        label="单价（元）"
        prop="unitPrice"
        min-width="120"
      ></el-table-column>
      <el-table-column align="center" label="数量" width="120">
        <el-input
          v-model="scope.row.count"
          slot-scope="scope"
          style="width: 80px"
          @input="handleCount(scope.row)"
          maxlength="3"
        ></el-input>
      </el-table-column>
      <el-table-column
        align="center"
        label="单位"
        prop="unit"
      ></el-table-column>
      <el-table-column
        align="center"
        label="原价（元）"
        min-width="100"
        prop="originalPrice"
      ></el-table-column>
      <el-table-column
        align="center"
        label="折扣（%）"
        prop="discount"
        width="110"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.unitPrice === '0.00'">100</span>
          <el-input
            v-else
            v-model="scope.row.discount"
            style="width: 90px"
            @input="handleDiscount(scope.row)"
          ></el-input>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="折后价格（元）"
        min-width="120"
        prop="discountPrice"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.unitPrice === '0.00'">0.00</span>
          <el-input-number
            v-else
            v-model="scope.row.discountPrice"
            :min="0"
            :precision="2"
            :controls="false"
            type="number"
            style="width: 90px"
            @input="handleDiscountPrice(scope.row)"
          ></el-input-number>
        </template>
      </el-table-column>
      <el-table-column align="center" label="医生" min-width="120">
        <template slot-scope="scope">
          <el-select v-model="scope.row.doctor" placeholder="请选择医生">
            <el-option
              v-for="option in doctorOptions"
              :key="option.label"
              :label="option.label"
              :value="option.value"
            ></el-option>
          </el-select>
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button size="mini" type="text" @click="handleDelete(scope)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-card class="mg20" shadow="never">
      <el-form inline size="mini">
        <el-form-item label="储值余额：" style="margin-bottom: 0"
          >¥ {{ remainingBalance }}</el-form-item
        >

        <el-form-item label="展开优惠选项：" style="margin-bottom: 0">
          <el-switch
            :value="preferential"
            @click.native="handlePreferential"
          ></el-switch>
        </el-form-item>
      </el-form>
    </el-card>
    <el-table v-if="preferential" :data="tableData" border>
      <el-table-column
        align="center"
        label="项目名称"
        min-width="150"
        prop="itemName"
      ></el-table-column>
      <el-table-column
        align="center"
        label="单价（元）"
        prop="unitPrice"
        min-width="120"
      ></el-table-column>
      <el-table-column
        align="center"
        label="数量"
        prop="count"
      ></el-table-column>
      <el-table-column
        align="center"
        label="实收（元）"
        min-width="120"
        prop="paidInPrice"
      ></el-table-column>
      <el-table-column
        align="center"
        label="储值金划扣金额（元）"
        min-width="160"
      >
        <el-input
          v-model="scope.row.petCardAmount"
          slot-scope="scope"
          @input="handlePetCardAmount(scope.row)"
        ></el-input>
      </el-table-column>
      <el-table-column align="center" label="优惠方式" min-width="170">
        <el-select
          v-model="scope.row.deductionType"
          slot-scope="scope"
          placeholder="请选择优惠方式"
          clearable
          @change="handleDeductionAmount($event, scope.row)"
        >
          <el-option
            v-for="discountCoupon in discountCouponOptions"
            :key="discountCoupon.value"
            :label="discountCoupon.label"
            :value="discountCoupon"
          ></el-option>
        </el-select>
      </el-table-column>
      <el-table-column
        align="center"
        label="优惠抵扣金额（元）"
        min-width="150"
        prop="deductionAmount"
      ></el-table-column>
    </el-table>
    <el-card class="mg20" shadow="never">
      <el-form inline size="mini">
        <el-row>
          <el-col :span="8">
            <el-form-item label="应缴金额：" style="margin-bottom: 0"
              >¥ {{ receivablePriceTotal }}</el-form-item
            >
          </el-col>
          <el-col :span="8">
            <el-form-item label="缴费金额：" style="margin-bottom: 0">
              <el-input :value="payAmount" @input="handlePayAmount"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="欠费金额：" style="margin-bottom: 0"
              >¥ {{ owingPriceTotal }}</el-form-item
            >
          </el-col>
        </el-row>
      </el-form>
    </el-card>
    <el-form class="mg20" inline size="mini">
      <el-form-item label="备注：">
        <el-input
          v-model="remarks"
          placeholder="请输入备注"
          style="width: 500px"
          type="textarea"
        ></el-input>
      </el-form-item>
    </el-form>
    <div class="mg20">
      <el-button
        :disabled="!tableData.length"
        :loading="loading"
        type="primary"
        @click="handleVerifyPayAmount"
        >确定</el-button
      >
      <el-button @click="handleCancel">取消</el-button>
      <span class="msg">
        {{
          twoAudit
            ? '（此订单需要二级审核）'
            : oneAudit
            ? '（此订单需要一级审核）'
            : ''
        }}
      </span>
    </div>
    <pay-allocation
      ref="payAllocation"
      @ok="handleVerifyDiscountAmount"
    ></pay-allocation>
  </el-card>
</template>

<script>
import dayjs from 'dayjs'
import { mapState } from 'vuex'
import { listStaff } from '@/api/services/common'
import { listPlan } from '@/api/services/plan'
import { sendBilling } from '@/api/services/billingMain'
import { deepCopy, compose } from '@/utils/utils'
import {
  billingProjectStatusEnum,
  billingTypeEnum,
  whetherFreeEnum,
} from '@/utils/enums'

import CtModules from '@/components/yiya/CtModules'
import PayAllocation from './PayAllocation'
import {
  computeOriginalPrice,
  computeDeductionAmount,
  computeDiscount,
  computeDiscountPrice,
  computePaidInPrice,
  computePetCardAmount,
  computeReceivablePrice,
  resetAmount,
} from './computed'
import { listMode } from '@/api/erp/mode'

export default {
  name: 'OrderEdit',
  components: {
    CtModules,
    PayAllocation,
  },
  props: {
    patient: {
      type: Object,
      default: () => ({}),
    },
    appointment: {
      type: Object,
      default: () => ({}),
    },
    tc: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      loading: false,
      checked: false,
      tableData: [],
      doctorList: [],
      restMap: {},
      remarks: '',
      payAmount: 0,
      balance: '0.00',
      discountCoupons: [],
      preferential: false,
    }
  },
  computed: {
    ...mapState({
      department: (state) => state.clinic.department,
      userName: (state) => state.user.name,
    }),
    whetherFreeEnum() {
      return whetherFreeEnum
    },
    doctorOptions() {
      return this.doctorList.filter((doctor) => !this.restMap[doctor.userId])
    },
    discountCouponOptions() {
      return this.discountCoupons.map((item) => ({
        label: item.name,
        value: item.deductionMoney.toFixed(2),
      }))
    },
    // 收费项目
    payItems() {
      return this.tableData.filter((i) => i.unitPrice !== '0.00')
    },
    // 原价总额
    originalPriceTotal() {
      return this.payItems
        .reduce((total, { originalPrice }) => total + +originalPrice, 0)
        .toFixed(2)
    },
    // 折后价格总额
    discountPriceTotal() {
      return this.payItems
        .reduce((total, { discountPrice }) => total + +discountPrice, 0)
        .toFixed(2)
    },
    // 总折扣
    discountTotal() {
      return (
        (this.discountPriceTotal / this.originalPriceTotal) *
        100
      ).toFixed(2)
    },
    // 储值金划扣总额
    petCardAmountTotal() {
      return this.payItems
        .reduce((total, { petCardAmount }) => total + +petCardAmount, 0)
        .toFixed(2)
    },
    // 优惠抵扣金额
    deductionAmountTotal() {
      return this.payItems
        .reduce((total, { deductionAmount }) => total + +deductionAmount, 0)
        .toFixed(2)
    },
    // 实收价格总额
    paidInPriceTotal() {
      return (+this.discountPriceTotal - +this.deductionAmountTotal).toFixed(2)
    },
    // 应收价格总额
    receivablePriceTotal() {
      return (+this.paidInPriceTotal - +this.petCardAmountTotal).toFixed(2)
    },
    // 欠费价格总额
    owingPriceTotal() {
      return (+this.receivablePriceTotal - +this.payAmount).toFixed(2)
    },
    oneAudit() {
      return this.twoAudit
        ? false
        : this.payItems.some(
            (item) =>
              +item.discountPrice - +item.deductionAmount <
              +item.price1 * +item.count
          )
    },
    twoAudit() {
      return this.payItems.some(
        (item) =>
          +item.discountPrice - +item.deductionAmount <
          +item.price2 * +item.count
      )
    },
    remainingBalance() {
      return (+this.balance - this.petCardAmountTotal).toFixed(2)
    },
  },
  mounted() {
    this.getListStaff()
    this.getListPlan()
    this.getDiscountCoupon()
  },
  methods: {
    createPriceMap(price) {
      return {
        // 单价
        unitPrice: price,
        // 数量
        count: 1,
        // 原价 = 单价 * 数量
        originalPrice: price,
        // 折扣
        discount: 100,
        // 折后价格 = 原价 * 折扣
        discountPrice: price,
        // 储值金划扣金额
        petCardAmount: '0.00',
        // 优惠抵扣金额
        deductionAmount: '0.00',
        // 已缴金额
        payAmount: price,
        // 实收价格 = 折后价格 - 优惠抵扣金额
        paidInPrice: '0.00',
        // 应收价格 = 实收价格 - 储值金划扣金额
        receivablePrice: price,
        // 欠费价格 = 应收价格 - 已缴金额
        // owingPrice: '0.00',
      }
    },
    addProject(e) {
      const {
        id: itemId,
        productItems: itemName,
        price,
        price1,
        price2,
        billingStatus,
        unit,
        isFree,
      } = e
      const { doctorName: doctor } = this.appointment
      const unitPrice = (isFree ? 0 : price).toFixed(2)
      const project = {
        ...this.createPriceMap(unitPrice),
        itemId,
        itemName,
        unit,
        doctor,
        billingStatus,
        toothPosition: '',
        deductionType: '',
        price1: price1.toFixed(2),
        price2: price2.toFixed(2),
        tradingStatus: billingTypeEnum['项目开单'],
      }
      this.pushProject(project)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    pushProject(...projects) {
      this.tableData.push(...projects)
    },
    async getDiscountCoupon() {
      const { rows } = await listMode()
      this.discountCoupons = rows
    },
    handleCount(project) {
      if (project.count == 0) {
        project.count = 1
      }
      project.count = Math.floor(project.count)
      compose(
        computeReceivablePrice,
        computePaidInPrice,
        computeDiscountPrice,
        computeOriginalPrice,
        resetAmount
      )(project)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    handleDiscount(project) {
      project.discount = Math.floor(
        Math.max(Math.min(project.discount, 100), 0)
      )
      compose(
        computeReceivablePrice,
        computePaidInPrice,
        computeDiscountPrice,
        resetAmount
      )(project)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    handlePetCardAmount(project) {
      compose(
        computeReceivablePrice,
        computePaidInPrice,
        computeDiscountPrice,
        computePetCardAmount
      )(project)
      if (+this.remainingBalance < 0) {
        project.petCardAmount = (
          +this.balance -
          (+this.petCardAmountTotal - +project.petCardAmount)
        ).toFixed(2)
      }
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    handleDeductionAmount(discountCoupon, project) {
      if (discountCoupon) {
        project.deductionType = discountCoupon.label
        project.deductionAmount = discountCoupon.value
      } else {
        project.deductionType = ''
        project.deductionAmount = '0.00'
      }
      compose(
        computeReceivablePrice,
        computePaidInPrice,
        computeDeductionAmount
      )(project)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    handleDiscountPrice(project) {
      project.discount = Math.max(
        Math.min(
          +((+project.discountPrice / +project.originalPrice) * 100).toFixed(2),
          100
        ),
        0
      )
      if (project.discount === 100) {
        project.discountPrice = project.originalPrice
      }
      compose(computeReceivablePrice, computePaidInPrice, resetAmount)(project)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    // getInt(val){
    //   return val>0 ? Math.floor(val):Math.ceil(val);
    // },
    handlePayAmount(e) {
      this.payAmount = Math.min(+e, +this.receivablePriceTotal) || 0
    },
    /**
     * 获取医生列表
     */
    async getListStaff() {
      const { data } = await listStaff({
        deptId: +this.department.deptId,
        postname: '医生',
      })
      this.doctorList = data.map(({ userName }) => ({
        label: userName,
        value: userName,
      }))
    },
    /**
     * 获取休息信息
     */
    async getListPlan() {
      const reservationDate = dayjs().format('YYYY-MM-DD')
      const { rows } = await listPlan({
        beginTime: reservationDate,
        endTime: reservationDate,
      })
      const map = {}
      rows.forEach((rest) => (map[rest.userId] = true))
      this.restMap = map
    },
    getSummaries({ columns }) {
      const sums = []
      columns.forEach((column, index) => {
        switch (column.label) {
          case '原价（元）':
            sums[index] = `${this.originalPriceTotal}元`
            break
          case '折扣（%）':
            sums[index] = `${this.discountTotal}%`
            break
          case '折后价格（元）':
            sums[index] = `${this.discountPriceTotal}元`
            break
          default:
            sums[index] = ''
        }
      })
      return sums
    },
    handleCancel() {
      this.$emit('cancel')
    },
    async handleDelete({ $index }) {
      await this.$confirm('删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      this.tableData = this.tableData.filter((_, i) => i !== $index)
      this.$nextTick(() => {
        this.payAmount = +this.receivablePriceTotal
      })
    },
    async handleVerifyPayAmount() {
      await this.$confirm('是否确认开单?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
      let tableData = deepCopy(this.tableData)
      if (this.owingPriceTotal !== '0.00') {
        let payAmountTotal = +this.payAmount
        tableData = tableData.map((project) => {
          const receivablePrice = +project.receivablePrice
          let payAmount = 0
          let owingPrice = 0
          if (payAmountTotal <= 0) {
            owingPrice = receivablePrice
          } else {
            if (payAmountTotal >= receivablePrice) {
              payAmount = receivablePrice
            } else {
              payAmount = payAmountTotal
              owingPrice = receivablePrice - payAmount
            }
            payAmountTotal -= receivablePrice
          }
          return {
            ...project,
            payAmount: payAmount.toFixed(2),
            owingPrice: owingPrice.toFixed(2),
          }
        })
        if (tableData.length !== 1) {
          this.$refs.payAllocation.open({
            tableData,
            receivablePriceTotal: this.receivablePriceTotal,
            payAmount: this.payAmount,
            owingPriceTotal: this.owingPriceTotal,
          })
          return
        }
      }
      this.handleVerifyDiscountAmount(tableData)
    },
    async handleVerifyDiscountAmount(tableData) {
      if (this.oneAudit || this.twoAudit) {
        await this.$confirm(
          `此订单需要${this.oneAudit ? '一级' : '二级'}审核，是否继续?`,
          '提示',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          }
        )
      }
      await this.handleBilling(tableData)
    },
    async handleBilling(tableData) {
      try {
        const { id: clinicPersonId, marketReservationId } = this.patient
        const { deptId: clinicId, deptName: clinic } = this.department
        const { id: appointmentId } = this.appointment
        const formData = {
          clinic,
          clinicId,
          billingPerson: this.userName,
          proposer: this.userName,
          thisPay: this.payAmount,
          type: billingTypeEnum['项目开单'],
          billingRemarks: this.remarks,
          arrearageChange: this.owingPriceTotal,
          personArrearage: this.owingPriceTotal,
        }
        formData.yiyaBillingMain = {
          allDiscount: this.discountTotal,
          appointmentId,
          clinic,
          clinicId,
          clinicPersonId,
          tc: this.tc !== '' ? this.tc : this.userName,
          marketReservationId,
          firstBilling: dayjs().format('YYYY-MM-DD HH:mm:ss'),
          originalPrice: this.originalPriceTotal,
          receivable: this.receivablePriceTotal,
          payAmount: this.payAmount,
        }
        formData.yiyaItemBillingExtends = tableData.map((item) => {
          const {
            itemId,
            itemName,
            count,
            unit,
            toothPosition,
            unitPrice,
            doctor,
            discount,
            deductionType: deductionMode,
            deductionAmount: deductionPrice,
            receivablePrice: projectReceivable,
            payAmount: thisPay,
            petCardAmount: storedDeductPrice,
          } = item
          return {
            itemId,
            itemName,
            discount,
            doctor,
            count,
            toothPosition,
            unit,
            unitPrice,
            deductionMode,
            deductionPrice,
            projectReceivable,
            projectReceived: '0.00',
            storedDeductPrice,
            thisPay,
          }
        })
        if (this.orderId) {
          formData.id = this.orderId
        }
        if (this.twoAudit) {
          formData.oneAudit = false
          formData.twoAudit = true
        } else {
          formData.oneAudit = this.oneAudit
          formData.twoAudit = false
        }
        this.loading = true
        await sendBilling(formData)
        this.oneAudit || this.twoAudit
          ? this.$message.warning('审核已提交')
          : this.msgSuccess('开单成功')
        this.handleCancel()
        this.$emit('ok')
      } finally {
        this.loading = false
      }
    },
    handlePreferential() {
      this.preferential = !this.preferential
      if (this.preferential === false) {
        this.tableData = this.tableData.map(resetAmount)
        this.payAmount = +this.receivablePriceTotal
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.order-edit {
  width: 100%;
  min-height: 600px;

  .mg20 {
    margin-top: 20px;
  }
}

.msg {
  color: red;
  font-size: 14px;
}
</style>
